#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/sysinfo.h>
#include <sys/vfs.h>
#include <error.h>

int mem_info(unsigned long * total, unsigned long * used, unsigned long * free)
{
	struct sysinfo info;

	sysinfo(&info);

	//printf("info.mem_unit =  %d\n", info.mem_unit);
	if ( info.mem_unit == 1 ) {
		info.mem_unit=1024;
		info.totalram /= info.mem_unit;
		info.freeram /= info.mem_unit;
	}

	*total = info.totalram;
	*used  = info.totalram - info.freeram;
	*free  = info.freeram;

	return 0;
}

int print_mem_info()
{	
	unsigned long total, used, free;

	mem_info(&total, &used, &free);
	
	printf("%6s%13s%13s%13s\n", "", "total", "used", "free");

	printf("%6s%13ld%13ld%13ld\n", "Mem:", total,
			used, free);

	printf("%6s %11.1fM %11.1fM %11.1fM\n", "Mem:", total/1024.0,
			used/1024.0, free/1024.0);
	
	return 0;
}

struct cpu_occupy
{
	char name[20];
	unsigned int user;		// use time
	unsigned int nice;		// nice time
	unsigned int system;	// syste time
	unsigned int idle;		// idle time
};

void get_cpuoccupy(struct cpu_occupy * cpu)
{
	FILE *fd;
	int n;
	char buff[256];
	struct cpu_occupy * cpu_tmp;

	cpu_tmp = cpu;

	fd = fopen("/proc/stat", "r");
	fgets(buff, sizeof buff, fd);
	sscanf(buff, "%s %u %u %u %u", &cpu_tmp->name, &cpu_tmp->user,
					&cpu_tmp->nice, &cpu_tmp->system, &cpu_tmp->idle);
	#if 0
	printf("buff:%s\n", buff);
	printf("name:%s\n", cpu_tmp->name);
	printf("user:%u\n", cpu_tmp->user);
	printf("nice:%u\n", cpu_tmp->nice);
	printf("system:%u\n", cpu_tmp->system);
	printf("idle:%u\n", cpu_tmp->idle);
	#endif
	fclose(fd);
}

float cal_cpu(struct cpu_occupy * old, struct cpu_occupy * new)
{
	unsigned long od, nd;
	unsigned long id, sd;
	float cpu_use = 0;

	od = (unsigned long)(old->user + old->nice + old->system + old->idle);	// first
	nd = (unsigned long)(new->user + new->nice + new->system + new->idle);	// second
	id = (unsigned long)(new->user - old->user);		// 用户第一次和第二次的时间差
	sd = (unsigned long)(new->system - old->system);	// 系统差.
	if ((nd - od) != 0)
		cpu_use = (float)((sd + id) * 100.0) / (nd - od);
	else
		cpu_use = 0.0;

	return cpu_use;
}

int cpu_use_rate(float * cpu)
{
	struct cpu_occupy old, new;

	get_cpuoccupy(&old);	
	sleep(5);
	get_cpuoccupy(&new);	
	*cpu = cal_cpu(&old, &new);
	
	return 0;
}

int print_cpu_rate()
{
	float cpu;

	cpu_use_rate(&cpu);
	printf("cpu:%3.1f\n", cpu);
}

#define Gsize (1024.00*1024.00*1024.00)
#define Msize (1024.00*1024.00)

#ifndef ARM_EXT3_SUPER_MAGIC
#define ARM_EXT3_SUPER_MAGIC	0x72b6
#endif /* ARM_EXT3_SUPER_MAGIC */

int flash_size(float * total, float * free)
{
	long long blocks,bfree;
	struct statfs fs;

	if(statfs("/",&fs)<0)
	{
		perror("statfs");
		exit(0);
	}

	blocks = fs.f_blocks;
	bfree = fs.f_bfree;

	if(fs.f_type==ARM_EXT3_SUPER_MAGIC) {
		*total = blocks * fs.f_bsize / Msize;
		*free  = bfree * fs.f_bsize / Msize;
	}
}

int print_flash_size()
{
	float total, free;

	flash_size(&total, &free);

	printf("%6s%13s%13s%13s\n", "", "total", "used", "free");

	printf("%6s %11.1fM %11.1fM %11.1fM\n", "Flash:", total,
			total - free, free);
}

int main()
{
	print_mem_info();
	//while(1)
	print_cpu_rate();
	print_flash_size();

	return 0;
}
